package chapter15;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author lzy
 * @create 2018-03-27 下午12:09
 */
public abstract class AbstractDao<T> implements IDao<T> {
    Connection connection;

    public AbstractDao(Connection connection) {
        this.connection = connection;
    }

    /**
     * 获取对象的全部属性值并存放到一个数组中
     *
     * @param emp
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    Object[] getObjectAttributes(Object emp) throws NoSuchFieldException, IllegalAccessException {
        int index = 0;
        Class<?> clazz = emp.getClass();
        Map<String, String> entryMap = DoMappingPo.getAttributeMap(clazz);
        Object[] params = new Object[entryMap.size()];
        for (Map.Entry<String, String> entry : entryMap.entrySet()) {
            Field field = clazz.getDeclaredField(entry.getValue());
            field.setAccessible(true);
            Object object = field.get(emp);
            params[index] = object;
            index += 1;
        }
        return params;
    }

    /**
     * 向preparedStatement中设置参数
     *
     * @param stmt
     * @param params
     * @throws SQLException
     */
    void setParams(PreparedStatement stmt, Object[] params) throws SQLException {
        int index = 1;
        for (Object parm : params) {
            if (parm instanceof String) {
                stmt.setString(index, parm.toString());
            } else if (parm instanceof Integer) {
                stmt.setInt(index, (Integer) parm);
            } else if (parm instanceof Date) {
                stmt.setDate(index, new java.sql.Date(((Date) parm).getTime()));
            } else if (parm instanceof Double) {
                stmt.setDouble(index, (Double) parm);
            }
            index += 1;
        }
    }

    /**
     * 从ResultSet中根据对象属性取出匹配数据并进行赋值
     *
     * @param field
     * @param rs
     * @param column
     * @param t
     * @throws SQLException
     * @throws IllegalAccessException
     */
    void setFieldValue(Field field, ResultSet rs, String column, T t) throws SQLException, IllegalAccessException {
        field.setAccessible(true);
        if (field.getType() == String.class) {
            String value = rs.getString(column);
            field.set(t, value);
        } else if (field.getType() == Integer.class) {
            Integer value = rs.getInt(column);
            field.set(t, value);
        } else if (field.getType() == Date.class) {
            Date value = new Date(rs.getDate(column).getTime());
            field.set(t, value);
        } else if (field.getType() == Double.class) {
            Double value = rs.getDouble(column);
            field.set(t, value);
        }
    }

    /**
     * 将RestultSet数据转换为对象列表
     *
     * @param rs
     * @param clazz
     * @return
     */
    List<T> getDoFromPo(ResultSet rs, Class<T> clazz) {
        Map<String, String> entryMap = PoMappingDo.getAttributeMap(clazz);
        List<T> list = new ArrayList<>();
        try {
            while (rs.next()) {
                T t = clazz.newInstance();
                for (Map.Entry<String, String> entry : entryMap.entrySet()) {
                    Field field = clazz.getDeclaredField(entry.getValue());
                    setFieldValue(field, rs, entry.getKey(), t);
                }
                list.add(t);
            }
        } catch (InstantiationException | IllegalAccessException | NoSuchFieldException | SQLException e) {
            e.printStackTrace();
        }
        return list;
    }
}
